////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                                            //
//                                                         WNProject                                                          //
//                                                                                                                            //
//            This file is distributed under the BSD 2-Clause open source license. See License.txt for details.               //
//                                                                                                                            //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include "WNScripting/inc/WNIdentifierMap.h"
#include "WNCore/inc/WNAssert.h"
#include "WNMemory/inc/WNAllocation.h"
#include "WNConcurrency/inc/WNCriticalSection.h"

using namespace WNMemory;
using namespace WNConcurrency;
using namespace WNScripting;


WNIdentifierMap::WNIdentifierMap() :
    mCurValue(0) {
}

WNIdentifierElement WNIdentifierMap::GetIdentifier(const WN_CHAR * _identifier, WN_SIZE_T _length) {
    #ifdef WN_SCRIPTING_MULTITHREADED_PARSING
        mIdentifierLock.Lock();
    #endif

    std::string s(_identifier, _length);
    WNIdentifierElement nextIter = WNInvalidIdentifier;
    WN_UNORDERED_MAP<std::string, WN_CHAR*>::iterator i = mIdentMap.find(s);
    if (i != mIdentMap.end()) {
        nextIter = (*i).second;
    } else {
        char * newstr = (WN_CHAR*)WNMalloc(_length + 1);
        memcpy(newstr, _identifier, sizeof(WN_CHAR) * (_length));
        newstr[_length] = '\0';
        mIdentMap.insert(std::pair<std::string, WN_CHAR*>(s, newstr));
        nextIter = newstr;
    }

    #ifdef WN_SCRIPTING_MULTITHREADED_PARSING
        mIdentifierLock.Unlock();
    #endif

    WN_RELEASE_ASSERT(WNIsValid(nextIter));

    return(nextIter);
}

const WN_CHAR* WNIdentifierMap::GetStringFromIdentifier(WNIdentifierElement _elem) const {
    return(static_cast<WN_CHAR*>(_elem));
}
